package com.hanyi.web.controller.system;

import java.util.List;
import java.util.Arrays;

import com.hanyi.system.domain.SysOfflineTask;
import com.hanyi.system.domain.SysRealtimeTask;
import com.hanyi.system.domain.vo.SysRealtimeTaskVo;
import com.hanyi.web.controller.task.ScheduleTask;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.hanyi.common.annotation.RepeatSubmit;
import com.hanyi.common.annotation.Log;
import com.hanyi.common.core.controller.BaseController;
import com.hanyi.common.core.domain.PageQuery;
import com.hanyi.common.core.domain.R;
import com.hanyi.common.core.validate.AddGroup;
import com.hanyi.common.core.validate.EditGroup;
import com.hanyi.common.core.validate.QueryGroup;
import com.hanyi.common.enums.BusinessType;
import com.hanyi.common.utils.poi.ExcelUtil;
import com.hanyi.system.domain.vo.SysOfflineTaskVo;
import com.hanyi.system.domain.bo.SysOfflineTaskBo;
import com.hanyi.system.service.ISysOfflineTaskService;
import com.hanyi.common.core.page.TableDataInfo;

/**
 * 离线任务
 *
 * @author grantfee
 * @date 2023-11-05
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/offlineTask")
public class SysOfflineTaskController extends BaseController {

    private final ISysOfflineTaskService iSysOfflineTaskService;

    private final ScheduleTask scheduleTask;
    /**
     * 查询离线任务列表
     */
    @SaCheckPermission("system:offlineTask:list")
    @GetMapping("/list")
    public TableDataInfo<SysOfflineTaskVo> list(SysOfflineTaskBo bo, PageQuery pageQuery) {
        return iSysOfflineTaskService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出离线任务列表
     */
    @SaCheckPermission("system:offlineTask:export")
    @Log(title = "离线任务", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(SysOfflineTaskBo bo, HttpServletResponse response) {
        List<SysOfflineTaskVo> list = iSysOfflineTaskService.queryList(bo);
        ExcelUtil.exportExcel(list, "离线任务", SysOfflineTaskVo.class, response);
    }

    /**
     * 获取离线任务详细信息
     *
     * @param taskId 主键
     */
    @SaCheckPermission("system:offlineTask:query")
    @GetMapping("/{taskId}")
    public R<SysOfflineTaskVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long taskId) {
        return R.ok(iSysOfflineTaskService.queryById(taskId));
    }

    /**
     * 新增离线任务
     */
    @SaCheckPermission("system:offlineTask:add")
    @Log(title = "离线任务", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysOfflineTaskBo bo) {
        return toAjax(iSysOfflineTaskService.insertByBo(bo) ? 1 : 0);
    }

    /**
     * 修改离线任务
     */
    @SaCheckPermission("system:offlineTask:edit")
    @Log(title = "离线任务", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysOfflineTaskBo bo) {
        return toAjax(iSysOfflineTaskService.updateByBo(bo) ? 1 : 0);
    }

    /**
     * 删除离线任务
     *
     * @param taskIds 主键串
     */
    @SaCheckPermission("system:offlineTask:remove")
    @Log(title = "离线任务", businessType = BusinessType.DELETE)
    @DeleteMapping("/{taskIds}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] taskIds) {
        return toAjax(iSysOfflineTaskService.deleteWithValidByIds(Arrays.asList(taskIds), true) ? 1 : 0);
    }

    /**
     * 启动实时任务
     *
     * @param taskId 主键
     */
    @SaCheckPermission("system:realtimeTask:query")
    @GetMapping("/start/{taskId}")
    public R<Void> startTask(@NotNull(message = "主键不能为空")
                                          @PathVariable Long taskId) {
        log.info("prepare to start offline task:"+taskId);
        //发送消息到边缘盒子启动任务
        SysOfflineTask task = iSysOfflineTaskService.queryByTaskId(taskId);
        boolean ok = scheduleTask.startRealTimeTask(task.getTaskId(),task.getOfflineStreamUrl());
        if(ok){
            task.setStatus("1");
            iSysOfflineTaskService.updateByEntity(task);
            return R.ok();
        }
        return R.fail("启动任务失败!请稍后重试");
    }

    /**
     * 停止实时任务
     *
     * @param taskId 主键
     */
    @SaCheckPermission("system:realtimeTask:query")
    @GetMapping("/stop/{taskId}")
    public R<Void> stopTask(@NotNull(message = "主键不能为空")
                                         @PathVariable Long taskId) {
        log.info("prepare to stop offline task:"+taskId);
        //发送消息到边缘盒子停止任务
        SysOfflineTask task = iSysOfflineTaskService.queryByTaskId(taskId);
        task.setStatus("0");
        iSysOfflineTaskService.updateByEntity(task);

        stopTaskAsync(taskId);
        return R.ok();
    }

    @Async
    protected void stopTaskAsync(long taskId){
        scheduleTask.stopTask(taskId);
    }
}
